import org.apache.commons.math3.distribution.NormalDistribution;
import sun.misc.BASE64Encoder;

import javax.annotation.Nullable;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.*;
import java.util.List;

public class JavaOperations {
    public void testListDelete()throws Exception{
        List<String> sources=new ArrayList<>();
        sources.add("第1个");
        sources.add("第2个");
        sources.add("第3个");
        sources.add("第4个");
        sources.add("第5个");
        for (int idx = 0; idx < sources.size(); idx++) {
            System.out.println(idx+" : "+sources.get(idx));
        }
        System.out.println("=====Seperation=====");
        //下面的方式，在删除过程中会报错（而foreach更会报错）
//        for (int idx = 0; idx < sources.size(); idx++) {
//            //删除掉偶数位置
//            //测试删除奇数位置的内容，会报错，因为后续的索引已经超出了
//            //测试删除偶数时不报错，会打印出原本第2和第5个元素
//            if (idx%2==0) {
//                sources.remove(idx);
//                idx--;
//            }
//            //如果是第0个元素的话，会报错
//            if (idx>0) {
//                System.out.println(sources.get(idx));
//            }
//        }
        Iterator<String> itSource=sources.iterator();
        while (itSource.hasNext()) {
            String valueCurrent=itSource.next();
//            System.out.println(valueCurrent);
            //执行了删除之后，后续要素的索引一直在变化
            if (sources.indexOf(valueCurrent)%2!=0) {
                System.out.println(valueCurrent + " 将被删除");
                itSource.remove();
            }
        }
        System.out.println("执行删除操作后，立即遍历原始集合的结果：");
        System.out.println("新的集合大小："+sources.size());
        for (int idx = 0; idx < sources.size(); idx++) {
            System.out.println(idx+" : "+sources.get(idx));
        }
    }
    public  void testPointEquals()throws Exception{
        /*
        * 结论：
        * 从测试可以看出，Java的Point自身已经考虑了相等的判断，也就是实际所需要的情况
        * 描述为：当两个点的x和y都相等时才能认为两个点是同一个点
        * */
        Double disTolerance=1e-8;
        Point pnt1=new Point();
        pnt1.setLocation(3.141593,5.723456);
        Point pnt2=new Point();
        pnt2.setLocation(3.141592,5.723457);
        System.out.println("原生方式判断");
        if (pnt1.equals(pnt2)) {
            System.out.println("小数位不一样时，两个点被判定为了相等。");
        }else {
            System.out.println("小数位不同时可以判断出两个点不相等");
        }
        if (pnt1.distance(pnt2)<disTolerance) {
            System.out.println("是同一个点");
            System.out.println(disTolerance.toString());
        }
        //自定义方法判断
        if (Point.distance(pnt1.getX(),pnt1.getY(),pnt2.getX(),pnt2.getY())<disTolerance) {
            System.out.println("两个点是同一个点");
        }else {
            System.out.println("两个点不是同一个点");
        }
        Point pnt3=new Point();
        pnt3.setLocation(3.141,5.72);
        System.out.println(pnt3.x);
        System.out.println(pnt3.y);
    }
    public void testUsingHashCode()throws Exception{
        /*
        * 哈希值：两个对象的值不同，则哈希值一定不同，反之，哈希值相等时，其值不一定是相等的。
        * 因此在Java内部判断两个对象是否equals时，会先判断两个对象的哈希值，如果不相等，那么两个对象一定不相等；如果相等时才需要进一步判断equals的逻辑
        * */
        Point pnt=new Point();
        pnt.setLocation(2.345,12.334);
        int testHash=pnt.hashCode();
        System.out.println(testHash);
        pnt=new Point();
        pnt.setLocation(77.6,33.2);
        System.out.println(pnt.hashCode());
    }

    public void test二维数组() {
        int rowCounts = 4, columnCount = 4;
        String[][] demo = new String[rowCounts][columnCount];
        for (int i = 0; i < rowCounts; i++) {
            for (int j = 0; j < columnCount; j++) {
                demo[i][j] = String.valueOf(i) + String.valueOf(j);
            }
        }
        System.out.println("二维数组的length：" + demo.length);
        System.out.println("二维数组的列数length：" + demo[0].length);
        //从foreach上也可以看出来，怎样去获取二维数组的行列值
        //即：直接使用length获取的是行数；必须使用某一行的数组的length才是列的数量
        for (String[] rows : demo) {
            for (String column : rows) {
                System.out.print(column + "  ");
            }
            System.out.println(System.lineSeparator());
        }
    }

    public void test计算概率分布(){
        double x=0.05;//这里的X是谁的值？是莫兰指数，还是其他的那个属性？
        //Parma1：平均值；Parma2：标准差
        NormalDistribution normalDistribution = new NormalDistribution(0.5, 3.2);
        System.out.println("数学期望："+normalDistribution.getMean());
        System.out.println("方差："+normalDistribution.getStandardDeviation());
        double v = normalDistribution.cumulativeProbability(x);
        v=Double.valueOf(String.format("%.8f", v));  //这里保存9位和vb中的WorksheetFunction.NORM.S.DIST(z,true)
        System.out.println("计算结果是："+v);
    }

    public void testJava的复制(    ) {
        double[][] arrSource = new double[3][3];
        Random random = new Random(10);
        DecimalFormat df = new DecimalFormat("#.000");
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                arrSource[i][j] = Double.valueOf(df.format(random.nextDouble()));
            }
        }
        System.out.println("原始数组是：");
        for (double[] row : arrSource) {
            for (double cln : row) {
                System.out.print(cln + "  ");
            }
            System.out.print(System.lineSeparator());
        }
        //===采用方法***===
//        double[][] arrCopy= Arrays.copyOf(arrSource,arrSource.length);
        double[][] arrCopy=new double[arrSource.length][];
        for (int i = 0; i < arrSource.length; i++) {
            arrCopy[i]=arrSource[i].clone();
        }
        //===采用clone的方式复制后，原始数组也发生了变化===
//        double[][] arrCopy = arrSource.clone();//二维数组是浅复制，只传递引用(一维数组是深复制)
        Arrays.sort(arrCopy[0]);//对复制后的数组第一行进行升序排列
        System.out.println("排序后的原始数组是：");
        for (double[] row : arrSource) {
            for (double cln : row) {
                System.out.print(cln + "  ");
            }
            System.out.print(System.lineSeparator());
        }
        System.out.println("排序后的新数组是：");
        for (double[] row : arrCopy) {
            for (double cln : row) {
                System.out.print(cln + "  ");
            }
            System.out.print(System.lineSeparator());
        }
        System.out.println("采用clone行法直接进行排序");
        for (double[] row : arrSource) {
            double[] rowCopy=row.clone();
            Arrays.sort(rowCopy);
            System.out.print(row[0]+"  ");
            System.out.print(rowCopy[0]);
            System.out.print(System.lineSeparator());
        }
    }

    public void test除法计算(){
        int n=5;
        double value=(-1)/(n-1);
        System.out.println("直接计算的结果："+value);
        double value2=(-1.0d)/(n-1);//如果是想要double类型的结果，必须这么写
        System.out.println("转换后的计算结果："+value2);
    }

    public void test度转为弧度() {
        double degree = 1;
        double radianMath = Math.toRadians(degree);
        System.out.println("Math转换结果：" + radianMath);
        double radianCalc = degree / 180 * Math.PI;
        System.out.println("Calculate转换结果：" + radianCalc);
    }

    public void test字符串分割(){
        //这种方式无法将1作为占位符，因为存在单引号
        String tmp= MessageFormat.format("{0}='{1}'","A","B");
        System.out.println("结果1："+tmp);
        String tmp2=MessageFormat.format("{0}=\'{1}\'","A","B");//这种方式无法拼接单引号
        System.out.println("结果2："+tmp2);
        String tmp3=String.format("%s='%s'","A","B");//这一种可以拼接单引号到结果中
        System.out.println("结果3："+tmp3);
        String srcPath="E:\\vectorOutput\\mygeo2shp_1_1.xls";
        String tmpjjjj="jdbc:postgresql://localhost:5432/gisdb";
        //无法直接使用.来作为分隔符，需要使用转义符而且是两个转义符
        String[] ttttt=srcPath.split("\\.");
        String[] ssssss=tmpjjjj.split("/");//此时一共分割成了4个数组，但是第二个是null
        System.out.println("字符串分割结果：数量是："+ttttt.length);
        System.out.println("分割结果："+ssssss[0]+ssssss[1]+ssssss[2]+ssssss[3]);
    }

    private void jjjjjj( Double pInput){
        //必须这样子判断是否为null，Double.isNaN判断的是输入值是否是一个数字，而不是为null的判断
        if (pInput==null||Double.isNaN(pInput)) {
            System.out.println("传了null的Double");
        }else
        {
            System.out.println("输入的值是："+pInput);
        }
    }

    public void testImageConversion(){
        String pathSvg="E:\\9.3Puyang\\PuYang_POI_Data\\icon\\foodservice.svg";//svg暂时不支持
        String pathPng="E:\\9.3Puyang\\PuYang_POI_Data\\Final_Data-Styles\\scenicspot.png";
        this.image2Base64(pathPng);
    }

    private void byte2Image(byte[] data,String path) {
        if (data.length < 3 || path.equals("")) return;
        try {
            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
            imageOutput.write(data, 0, data.length);
            imageOutput.close();
            System.out.println("Make Picture success,Please find image in " + path);
        } catch (Exception ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
        }
    }

    private void image2Base64(String imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            File tmpFile=new File(imgPath);
            System.out.println(tmpFile.getName());
            InputStream in = new FileInputStream(imgPath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回Base64编码过的字节数组字符串
        System.out.println("本地图片转换Base64:" + encoder.encode(Objects.requireNonNull(data)));
    }

}
